package com.ossean.match.matchprocess;

import java.io.IOException;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.ossean.match.dao.RelativeMemoDao;
import com.ossean.match.dao.RelativeMemoToOpenSourceProjectDao;
import com.ossean.match.lucene.LuceneIndex;
import com.ossean.match.lucene.LuceneSearch;
import com.ossean.match.model.Project;
import com.ossean.match.model.RelativeMemo;
import com.ossean.match.model.RelativeMemoToOpenSourceProject;
import com.ossean.match.utils.Normalizer;

import javax.annotation.Resource;

@Component("match")
public class Match {
	private Logger logger = LoggerFactory.getLogger(getClass());
	private double titleWeight = 0.8;
	private double threshholdWeight = 0.6;

	@Resource
	private RelativeMemoToOpenSourceProjectDao matchResultDao;
	@Resource
	private RelativeMemoDao relativeMemoDao;

	/**
	 * projects match to memos
	 * 
	 * @param projects
	 * @param prjHistory
	 * @param memoHistory
	 * @param tagOperator
	 * @param matchResultOperator
	 */
	public void prjToMemoMatch(List<Project> projects, MatchIncrement matchIncrement) {
		HashMap<Integer, MemoInfos> matchMap = new HashMap<Integer, MemoInfos>();
		try {
			Directory memoDire = FSDirectory.open(Paths
					.get(LuceneIndex.MEMOS_INDEX_PATH));
			Directory prjDire = FSDirectory.open(Paths
					.get(LuceneIndex.PRJS_INDEX_PATH));
			if (!DirectoryReader.indexExists(memoDire)) { // if the index directory
														// doesn't exist
				return;
			}
			IndexReader memoIndexReader = DirectoryReader.open(memoDire);
			IndexReader prjIndexReader = DirectoryReader.open(prjDire);
			int prjId = 0;
			String prjName = "";
			String prjTags = "";
			for(Project project : projects) {
				prjId = project.getId();																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																		                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
				prjTags = (Normalizer.normalize(project.getTags())).toLowerCase();
				prjName = (Normalizer.normalize(project.getName())).toLowerCase();
				if (prjName == null || prjName == "")
					continue;
				// 项目名匹配帖子内容
				if (prjName.length() >= 2 && !Normalizer.isAllNumber(prjName)) {
					matchMap = LuceneSearch.prjToMemoMatchByLucene(prjName, 
							   LuceneIndex.contentFieldName, titleWeight, matchMap, memoIndexReader, prjIndexReader, matchIncrement);
				}
				// 用项目标签搜索帖子内容
//				if (prjTags != null && prjTags.length() > 0 && matchMap.size() > 0) {
//					List<String> prjTagsList = Normalizer.tagsSegmentation(project.getTags().toLowerCase());
//					for (String prjTag : prjTagsList) {
//						matchMap = LuceneSearch.searchByPrjTag(
//								prjTag, LuceneIndex.contentFieldName, LuceneIndex.memoIdFieldName, prjTagsToMemoTitleWeight,
//								matchMap, memoIndexReader);
//					}
//				}
				if (matchMap.size() > 0)
					insertPrjToMemoMatchResult(prjId, matchMap);
				matchMap.clear();
				logger.info("current prjId: " + prjId);
			}
			memoIndexReader.close();
			memoDire.close();
			prjIndexReader.close();
			prjDire.close();
		} catch (IOException e) {
			logger.error("prjToMemoMatch io error in Match: " + e);
		}
	}
	
	/**
	 *项目匹配帖子结果入库
	 * @param prjId
	 * @param matchMap
	 */
	@Transactional(propagation=Propagation.REQUIRES_NEW)
	public void insertPrjToMemoMatchResult(int prjId, HashMap<Integer, MemoInfos> matchMap) {
		for (Map.Entry<Integer, MemoInfos> entry : matchMap.entrySet()) {
			try {
				int memoId = entry.getKey();
				double weight = entry.getValue().getWeight();
				String experience = entry.getValue().getExperience();
				String city = entry.getValue().getCity();
				int minSalary = entry.getValue().getMin_salary();
				int maxSalary = entry.getValue().getMax_salary();
				if (weight > threshholdWeight) {
					RelativeMemoToOpenSourceProject matchResult = new RelativeMemoToOpenSourceProject();
					matchResult.setOsp_id(prjId);
					matchResult.setRelative_memo_id(memoId);
					matchResult.setMatch_weight(weight);
					matchResult.setCity(city);
					matchResult.setExperience(experience);
					matchResult.setMin_salary(minSalary);
					matchResult.setMax_salary(maxSalary);
					matchResultDao.insertMatchResult(getTargetTable(prjId), matchResult);
				}
			} catch (Exception e) {
				logger.error("insertPrjToMemoMatchResult error: " + e);
			}
		}
	}
	
	/**
	 * get the match result table's name
	 * @param osp_id
	 * @return
	 */
	public static String getTargetTable(int osp_id){
//		String targetTableName = "";
//		if (osp_id < 500) {
//			targetTableName = "relative_memo_to_open_source_projects_1";
//		}
//		else if (osp_id >= 500 && osp_id < 1000) {
//			targetTableName = "relative_memo_to_open_source_projects_2";
//		}
//		else if (osp_id >= 1000 && osp_id < 1500) {
//			targetTableName = "relative_memo_to_open_source_projects_3";
//		}
//		else if (osp_id >= 1500 && osp_id < 2000) {
//			targetTableName = "relative_memo_to_open_source_projects_4";
//		}
//		else if (osp_id >= 2000 && osp_id < 3000) {
//			targetTableName = "relative_memo_to_open_source_projects_5";
//		}
//		else if (osp_id >= 3000 && osp_id < 5000) {
//			targetTableName = "relative_memo_to_open_source_projects_6";
//		}
//		else if (osp_id >= 5000 && osp_id < 7500) {
//			targetTableName = "relative_memo_to_open_source_projects_7";
//		}
//		else if (osp_id >= 7500 && osp_id < 10000) {
//			targetTableName = "relative_memo_to_open_source_projects_8";
//		}
//		else if (osp_id >= 10000 && osp_id < 310000) {
//			int a = 7 + osp_id/5000;
//			targetTableName = "relative_memo_to_open_source_projects_" + a;
//		}
//		else if (osp_id >= 310000) {
//			targetTableName = "relative_memo_to_open_source_projects_70";
//		}
		//return targetTableName;
		return "highcharts";
	}

	/**
	 * memos match to projects
	 * 
	 * @param memos
	 * @param prjHistory
	 * @param memoHistory
	 * @param tagOperator
	 * @param matchResultOperator
	 */
	public void memoToPrjMatch(List<RelativeMemo> memos, MatchIncrement matchIncrement) {
		HashMap<Integer, Double> matchMap = new HashMap<Integer, Double>();
		try {
			Directory dire = FSDirectory.open(Paths
					.get(LuceneIndex.PRJS_INDEX_PATH));
			if (!DirectoryReader.indexExists(dire)) { // if the index directory
														// doesn't exist
				return;
			}
			IndexReader indexReader = DirectoryReader.open(dire);
			int memoId = 0;
			String memoContent = "";
			for(RelativeMemo memo : memos) {
				memoId = memo.getId();
				if (memo.getContent() == null || memo.getContent().length() == 0) {
					continue;
				}
				memoContent = memo.getContent().toLowerCase();
				if (memoContent.length() == 0) {
					continue;
				}
				if (Normalizer.isAllNumber(memoContent)) {
					continue;
				}
				// 帖子标题匹配项目名
				List<String> memoContentList = Normalizer.getList(memoContent);
				if (memoContentList.size() > 0) {
					matchMap = LuceneSearch.memoToPrjMatchByLucene(memoContent,
							memoContentList, LuceneIndex.prjNameFieldName,
							titleWeight, matchMap, indexReader);
				}
//				if (matchMap.size() > 0) {
//					// 帖子标题匹配项目标签
//					if (memoContentList != null && memoContentList.size() > 0) {
//						for (String memoContentTerm :memoContentList) {
//							matchMap = LuceneSearch.searchByMemoContentList(
//									memoContentTerm, LuceneIndex.prjTagsFieldName, LuceneIndex.prjIdFieldName, prjTagsToMemoTitleWeight,
//									matchMap, indexReader);
//						}
//					}
//				}
				if (matchMap.size() > 0)
					insertMemoToPrjMatchResult(memoId, matchMap, matchIncrement);

				matchMap.clear();
				logger.info("current MemoId: " + memoId);
			}
			indexReader.close();
			dire.close();
		} catch (Exception e) {
			logger.error("memoToPrjMatch error in Match: " + e);
		}
	}
	
	/**
	 * 帖子匹配项目结果入库
	 * @param memoId
	 * @param matchMap
	 */
	@Transactional(propagation=Propagation.REQUIRES_NEW)
	public void insertMemoToPrjMatchResult(int memoId, HashMap<Integer, Double> matchMap, MatchIncrement matchIncrement) {
		RelativeMemo memo = relativeMemoDao.getMemoById(memoId);
		String experience = memo.getExperience();
		String city = "";
		for (int i = 0; i < matchIncrement.getCityList().size(); i++) {
            if(memo.getAddr().contains(matchIncrement.getCityList().get(i))){
            	city = matchIncrement.getCityList().get(i);
            }
        }
		String salaryNum = Normalizer.StringFilter(memo.getSalary());
		int []salaries = new int[]{0,0};
		int j = 0;
		for(String num : salaryNum.split(" ")){
        	if (num.trim().length() > 0) {
        		salaries[j] = Integer.parseInt(num);
        		j++;
			}
		}
		int minSalary = salaries[0];
		int maxSalary = salaries[1];
		for (Map.Entry<Integer, Double> entry : matchMap.entrySet()) {
			try {
				int prjId = entry.getKey();
				double weight = entry.getValue();
				if (weight > threshholdWeight) {
					RelativeMemoToOpenSourceProject matchResult = new RelativeMemoToOpenSourceProject();
					matchResult.setOsp_id(prjId);
					matchResult.setRelative_memo_id(memoId);
					matchResult.setMatch_weight(weight);
					matchResult.setCity(city);
					matchResult.setExperience(experience);
					matchResult.setMin_salary(minSalary);
					matchResult.setMax_salary(maxSalary);
					matchResultDao.insertMatchResult(getTargetTable(prjId), matchResult);
				}
			} catch (Exception e) {
				logger.error("insertMemoToPrjMatchResult error: " + e);
			}
		}
	}

}
